home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (c) 1994 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and
- * its documentation for any purpose is hereby granted without fee,
- * provided that (i) the above copyright notices and this permission
- * notice appear in all copies of the software and related documentation,
- * and (ii) the name of Silicon Graphics may not be used in any
- * advertising or publicity relating to the software without the specific,
- * prior written permission of Silicon Graphics.
- *
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
- *
- * IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR ANY SPECIAL,
- * INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY
- * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
- * OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
- * OF THIS SOFTWARE.
- */
- /*
- * surfgrid.c - demonstration of polygon_offset extension
- *
- * 1994 Simon Hui - Silicon Graphics Computer Systems
- *
- * $Revision: 1.1 $
- *
- * usage:
- * surfgrid [-f (full screen)] [-h(elp)]
- *
- * The program displays a torus made of bezier patches. The outline of the
- * patches is displayed as lines drawn on the surface. polygon_offset is used to
- * displace the depth of the patches so it does not interfere with the lines.
- *
- * keys:
- * p toggle polygon offset
- * m toggle multisampling
- * s toggle surface drawing
- * g toggle grid drawing
- * f toggle smooth/flat shading
- * n toggle whether to use GL evaluators or GLU nurbs
- * u decr number of segments in U direction
- * U incr number of segments in U direction
- * v decr number of segments in V direction
- * V incr number of segments in V direction
- * h help
- * escape quit
- *
- */
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <math.h>
- #include <GL/glu.h>
- #include <GL/glx.h>
- #include <X11/keysym.h>
- #include <Xm/MwmUtil.h>
- #include "util.h"
-
- #define W 600
- #define H 600
-
- static long winwidth = W, winheight = H;
- GC xgc;
- Display *dpy;
- Colormap cmap;
- Window window;
- XVisualInfo *vi;
- GLXContext cx;
- GLUnurbsObj *nobj;
- GLuint surflist, gridlist;
-
- int useglunurbs = 0;
- int smooth = 1;
- int tracking = 0;
- int showgrid = 1;
- int showsurf = 1;
- GLboolean hasMultisampling;
- float modelmatrix[16] = {
- 1, 0, 0, 0,
- 0, 1, 0, 0,
- 0, 0, 1, 0,
- 0, 0, 0, 1,
- };
-
- float scale = 0.5;
- float bias = 0.002;
- int usegments=4;
- int vsegments=4;
-
- int spindx, spindy;
- int startx, starty;
- int curx, cury;
-
- void redraw(void);
- void createlists(void);
- Window createwindow(int argc, char **argv, Bool fullscreen);
-
- float torusnurbpts[], torusbezierpts[];
-
- void eventloop( void )
- {
- XEvent event;
- XButtonEvent *bev;
- int x, y, size;
- unsigned int w, h, bw, depth;
- Window root;
-
- for (;;) {
- if (XPending(dpy)) {
- XNextEvent(dpy, &event);
- bev = (XButtonEvent *) &event;
- switch (event.type) {
- case KeyPress:
- {
- char buf[100];
- int rv;
- KeySym ks;
-
- rv = XLookupString(&event.xkey, buf, sizeof(buf), &ks, 0);
- switch (ks) {
- case XK_n:
- useglunurbs = !useglunurbs;
- break;
- #ifdef GL_EXT_polygon_offset
- case XK_p:
- if (glIsEnabled( GL_POLYGON_OFFSET_EXT )) {
- glDisable( GL_POLYGON_OFFSET_EXT );
- printf("disabling polygon offset\n");
- } else {
- glEnable( GL_POLYGON_OFFSET_EXT );
- printf("enabling polygon offset\n");
- }
- break;
- #endif
- #ifdef GL_SGIS_multisample
- case XK_m:
- if (hasMultisampling) {
- if (glIsEnabled( GL_MULTISAMPLE_SGIS )) {
- glDisable( GL_MULTISAMPLE_SGIS );
- printf("Multisampling off\n");
- } else {
- glEnable( GL_MULTISAMPLE_SGIS );
- printf("Multisampling on\n");
- }
- }
- break;
- #endif
- case XK_g:
- showgrid = !showgrid;
- break;
- case XK_t:
- showsurf = !showsurf;
- break;
- case XK_f:
- smooth = !smooth;
- if (smooth) {
- glShadeModel( GL_SMOOTH );
- } else {
- glShadeModel( GL_FLAT );
- }
- break;
- case XK_S:
- scale += 0.1;
- printf( "scale: %g\n", scale);
- break;
- case XK_s:
- scale -= 0.1;
- printf( "scale: %g\n", scale);
- break;
- case XK_B:
- bias += 0.0001;
- printf( "bias: %g\n", bias);
- break;
- case XK_b:
- bias -= 0.0001;
- printf( "bias: %g\n", bias);
- break;
- case XK_u:
- if (usegments > 1)
- usegments--;
- createlists();
- break;
- case XK_U:
- usegments++;
- createlists();
- break;
- case XK_v:
- if (vsegments > 1)
- vsegments--;
- createlists();
- break;
- case XK_V:
- vsegments++;
- createlists();
- break;
- case XK_h:
- case XK_question:
- printf("Keys:\tp - toggle polygon offset\n");
- printf("\tb/B - decr/incr polygon offset bias\n");
- printf("\ts/S - decr/incr polygon offset scale\n");
- printf("\tm - toggle multisampling\n");
- printf("\tt - toggle surface drawing\n");
- printf("\tg - toggle grid drawing\n");
- printf("\tf - toggle smooth/flat shading\n");
- printf("\tn - toggle between GL evaluators\
- and GLU nurbs\n");
- printf("\tu/U - decr/incr number of segments\
- in U direction\n");
- printf("\tv/V - decr/incr number of segments\
- in V direction\n");
- printf("\th/? - help\n");
- printf("\tEsc - quit\n");
- printf("To move the object press a mouse button\
- and move the mouse\n");
- break;
- case XK_Escape:
- exit(EXIT_SUCCESS);
- break;
- }
- if (!XPending(dpy)) redraw();
- }
- break;
- case Expose:
- XGetGeometry(dpy, window, &root, &x, &y, &w, &h, &bw, &depth);
- winwidth = w;
- winheight = h;
- size = (winwidth < winheight ? winwidth : winheight);
- glViewport((winwidth-size)/2, (winheight-size)/2, size, size);
- redraw();
- break;
- case ConfigureNotify:
- winwidth = event.xconfigure.width;
- winheight = event.xconfigure.height;
- size = (winwidth < winheight ? winwidth : winheight);
- glViewport((winwidth-size)/2, (winheight-size)/2, size, size);
- redraw();
- break;
- case ButtonPress:
- curx = startx = bev->x;
- cury = starty = bev->y;
- spindx = 0;
- spindy = 0;
- tracking = True;
- break;
- case ButtonRelease:
- /*
- * If user released the button while moving the mouse, keep
- * spinning.
- */
- if (bev->x != curx || bev->y != cury) {
- spindx = bev->x - curx;
- spindy = bev->y - cury;
- }
- tracking = False;
- break;
- case MotionNotify:
- if (XPending(dpy))
- break;
- curx = bev->x;
- cury = bev->y;
- if (curx != startx || cury != starty) {
- redraw();
- startx = curx;
- starty = cury;
- }
- break;
- }
- } else {
- if (!tracking && (spindx!=0 || spindy!=0)) {
- redraw();
- }
- }
- }
- }
-
- void gridmaterials(void)
- {
- float front_mat_diffuse[] = { 0, 0, 0, 0 };
- float front_mat_ambient[] = { 0, 0, 0, 0 };
- float back_mat_diffuse[] = { 0, 0, 0, 0 };
- float back_mat_ambient[] = { 0, 0, 0, 0 };
-
- glMaterialfv(GL_FRONT, GL_DIFFUSE, front_mat_diffuse);
- glMaterialfv(GL_FRONT, GL_AMBIENT, front_mat_ambient);
- glMaterialfv(GL_BACK, GL_DIFFUSE, back_mat_diffuse);
- glMaterialfv(GL_BACK, GL_AMBIENT, back_mat_ambient);
- }
-
- void surfacematerials(void)
- {
- float front_mat_diffuse[] = { 0.2, 0.7, 0.4, 1.0 };
- float front_mat_ambient[] = { 0.1, 0.1, 0.1, 1.0 };
- float back_mat_diffuse[] = { 1.0, 1.0, 0.2, 1.0 };
- float back_mat_ambient[] = { 0.1, 0.1, 0.1, 1.0 };
-
- glMaterialfv(GL_FRONT, GL_DIFFUSE, front_mat_diffuse);
- glMaterialfv(GL_FRONT, GL_AMBIENT, front_mat_ambient);
- glMaterialfv(GL_BACK, GL_DIFFUSE, back_mat_diffuse);
- glMaterialfv(GL_BACK, GL_AMBIENT, back_mat_ambient);
- }
-
- void init(int argc, char **argv, int fullscreen)
- {
- int i;
- float ambient[] = { 0.0, 0.0, 0.0, 1.0 };
- float diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
- float position[] = { 90.0, 90.0, -150.0, 0.0 };
- float lmodel_ambient[] = { 1.0, 1.0, 1.0, 1.0 };
- float lmodel_twoside[] = { GL_TRUE };
-
- window = createwindow( argc, argv, fullscreen );
- cx = glXCreateContext(dpy, vi, 0, GL_TRUE);
- if (!glXMakeCurrent(dpy, window, cx)) {
- fprintf(stderr, "Can't make window current to context\n");
- exit(EXIT_FAILURE);
- }
- if (!getExtension("GL_EXT_polygon_offset")) {
- fprintf(stderr, "Sorry GL_EXT_polygon_offset is not supported.\n");
- exit(EXIT_FAILURE);
- }
- glLineWidth(2);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- gluPerspective( 40.0, 1.0, 2.0, 200.0 );
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
-
- glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
- glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
- glLightfv(GL_LIGHT0, GL_POSITION, position);
- glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
-
- glEnable(GL_LIGHTING);
- glEnable(GL_LIGHT0);
- glEnable(GL_DEPTH_TEST);
- glEnable(GL_AUTO_NORMAL);
- glFrontFace(GL_CCW);
-
- glEnable( GL_MAP2_VERTEX_4 );
- glClearColor(0.25, 0.25, 0.5, 0.0);
-
- #ifdef GL_EXT_polygon_offset
- glEnable(GL_POLYGON_OFFSET_EXT);
- glPolygonOffsetEXT( scale, bias );
- #endif
- nobj = gluNewNurbsRenderer();
- gluNurbsProperty(nobj, GLU_SAMPLING_METHOD, GLU_DOMAIN_DISTANCE );
-
- surflist = glGenLists(1);
- gridlist = glGenLists(1);
- createlists();
- }
-
- void drawmesh(void)
- {
- int i, j;
- float *p;
-
- int up2p = 4;
- int uorder = 3, vorder = 3;
- int nu = 4, nv = 4;
- int vp2p = up2p * uorder * nu;
-
- for (j=0; j < nv; j++) {
- for (i=0; i < nu; i++) {
- p = torusbezierpts + (j * vp2p * vorder) + (i * up2p * uorder);
- #ifdef GL_EXT_polygon_offset
- glPolygonOffsetEXT( scale, bias );
- #endif
- glMap2f( GL_MAP2_VERTEX_4, 0.0, 1.0, up2p, 3, 0.0, 1.0, vp2p, 3,
- (void*)p );
- if (showsurf) {
- surfacematerials();
- glEvalMesh2( GL_FILL, 0, usegments, 0, vsegments );
- }
- if (showgrid) {
- gridmaterials();
- glEvalMesh2( GL_LINE, 0, usegments, 0, vsegments );
- }
- }
- }
- }
-
- void redraw(void)
- {
- static int i=0;
- int dx, dy;
- float v[3], n[3], rot[3];
- float len, rlen, ang;
- static GLuint vcount;
-
- glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
- glColor3f( 1, 0, 0);
-
- if (tracking) {
- dx = curx - startx;
- dy = cury - starty;
- } else {
- dx = spindx;
- dy = spindy;
- }
- if (dx || dy) {
- dy = -dy;
- v[0] = dx;
- v[1] = dy;
- v[2] = 0;
-
- len = length(v);
- ang = -len / 600 * 360;
- norm( v );
- cross( v, z_axis, rot );
-
- /*
- ** We concatenate the rotation onto the current modelview matrix and
- ** read the matrix back, thus saving ourselves from writing our own
- ** matrix manipulation routines.
- ** This is certainly not recommended for programs that care
- ** about performance or numerical stability :-)
- */
- glLoadIdentity();
- glRotatef(ang, rot[0], rot[1], rot[2]);
- glMultMatrixf(modelmatrix);
- glGetFloatv(GL_MODELVIEW_MATRIX, modelmatrix);
- }
- glLoadIdentity();
- glTranslatef( 0.0, 0.0, -10.0 );
- glMultMatrixf(modelmatrix);
-
- if (useglunurbs) {
- if (showsurf) glCallList(surflist);
- if (showgrid) glCallList(gridlist);
- } else {
- glMapGrid2f( usegments, 0.0, 1.0, vsegments, 0.0, 1.0 );
- drawmesh();
- }
-
- glXSwapBuffers(dpy, window);
- }
-
- static void usage(char *name, int exitStatus)
- {
- fprintf(stderr, "usage: %s [-f (for full screen)] [-h(elp)]\n", name);
- fprintf(stderr,
- "\tInteractively, `h/?' keys provide description of interface\n");
- exit(exitStatus);
- }
-
- void
- main(int argc, char **argv)
- {
- int i, ms, fullscreen = 0;
-
- for (i=1; i<argc; i++) {
- if (argv[i][0] == '-') {
- switch (argv[i][1]) {
- case 'f':
- fullscreen = 1;
- break;
- case 'h':
- usage(argv[0], EXIT_SUCCESS);
- default:
- usage(argv[0], EXIT_FAILURE);
- }
- } else {
- usage(argv[0], EXIT_FAILURE);
- }
- }
-
- init(argc, argv, fullscreen);
- eventloop();
- glXMakeCurrent(dpy, None, NULL);
- glXDestroyContext(dpy, cx);
- XCloseDisplay(dpy);
- }
-
- /****************************************************************************/
-
- float circleknots[] = { 0.0, 0.0, 0.0, 0.25, 0.50, 0.50, 0.75, 1.0, 1.0, 1.0 };
-
- void createlists(void)
- {
- gluNurbsProperty(nobj, GLU_U_STEP, (usegments-1)*4 );
- gluNurbsProperty(nobj, GLU_V_STEP, (vsegments-1)*4 );
-
- gluNurbsProperty(nobj, GLU_DISPLAY_MODE, GLU_FILL);
- glNewList(surflist, GL_COMPILE);
- surfacematerials();
- gluBeginSurface(nobj);
- gluNurbsSurface(nobj, 10, circleknots, 10, circleknots,
- 4, 28, torusnurbpts, 3, 3, GL_MAP2_VERTEX_4);
- gluEndSurface(nobj);
- glEndList();
-
- gluNurbsProperty(nobj, GLU_DISPLAY_MODE, GLU_OUTLINE_POLYGON);
- glNewList(gridlist, GL_COMPILE);
- gridmaterials();
- gluBeginSurface(nobj);
- gluNurbsSurface(nobj, 10, circleknots, 10, circleknots,
- 4, 28, torusnurbpts, 3, 3, GL_MAP2_VERTEX_4);
- gluEndSurface(nobj);
- glEndList();
- }
-
- /****************************************************************************/
-
- /*
- * Create an X window.
- */
-
- static Bool WaitForMapNotify(Display *d, XEvent *e, char *arg)
- {
- if ((e->type == MapNotify) && (e->xmap.window == (Window)arg)) {
- return GL_TRUE;
- }
- return GL_FALSE;
- }
-
- Window createwindow(int argc, char **argv, Bool fullscreen)
- {
- Window window;
- XSetWindowAttributes swa;
- unsigned int width, height;
- XSizeHints sh;
- XEvent event;
- const char *extensions;
- char title[100];
- int attributes[] = {
- #ifdef GL_SGIS_multisample
- GLX_SAMPLES_SGIS,
- #else
- None, /* Note used - simplifies the code */
- #endif
- 0,
- GLX_RGBA,
- GLX_DOUBLEBUFFER,
- GLX_RED_SIZE, 1,
- GLX_GREEN_SIZE, 1,
- GLX_BLUE_SIZE, 1,
- GLX_DEPTH_SIZE, 1,
- None,
- };
-
- dpy = XOpenDisplay(0);
- if (!dpy) {
- fprintf(stderr, "Can't connect to display \"%s\"\n",
- getenv("DISPLAY"));
- exit(EXIT_FAILURE);
- }
- #ifdef GL_SGIS_multisample
- extensions = glXQueryExtensionsString(dpy, DefaultScreen(dpy));
- hasMultisampling = extensions == NULL ||
- strstr(extensions, "GLX_SGIS_multisample") == NULL;
- #else
- hasMultisampling = GL_FALSE;
- #endif
- if (hasMultisampling) {
- int logMs;
- /* Try to get the largest number of samples */
- for (vi = NULL, logMs = 4; logMs && vi == NULL; logMs--) {
- attributes[1] = logMs > 1 ? 1 << logMs : 0;
- vi = glXChooseVisual(dpy, DefaultScreen(dpy), attributes);
- }
- sprintf(title,"%s - %d samples", argv[0], attributes[1]);
- } else {
- vi = glXChooseVisual(dpy, DefaultScreen(dpy), &attributes[2]);
- sprintf(title,"%s", argv[0]);
- }
- if (!vi) {
- fprintf(stderr, "Cannot find visual on \"%s\"\n", getenv("DISPLAY"));
- exit(EXIT_FAILURE);
- }
-
- cmap = XCreateColormap(dpy, RootWindow(dpy, vi->screen), vi->visual,
- AllocNone);
- swa.background_pixel = 0;
- swa.border_pixel = 0;
- swa.colormap = cmap;
- swa.event_mask = ExposureMask | StructureNotifyMask | KeyPressMask |
- KeyReleaseMask | ButtonPressMask | ButtonMotionMask | ButtonReleaseMask;
-
- if (fullscreen) {
- width = DisplayWidth( dpy, 0 );
- height = DisplayHeight( dpy, 0 );
- sh.x = 0;
- sh.y = 0;
- } else {
- width = winwidth;
- height = winheight;
- sh.x = 50;
- sh.y = 50;
- }
- sh.flags = USPosition | PPosition;
- window = XCreateWindow(dpy, RootWindow(dpy, vi->screen), sh.x, sh.y,
- width, height,
- 0, vi->depth, InputOutput, vi->visual,
- CWBorderPixel|CWColormap|CWEventMask|CWBackPixel,
- &swa);
- XSetStandardProperties(dpy, window, title, argv[0], None, argv, argc, &sh);
- XSetWMColormapWindows(dpy, window, &window, 1);
- if (fullscreen) {
- /* turn off window decorations */
- Atom hints_atom;
- MotifWmHints hints;
-
- hints_atom = XInternAtom( dpy, "_MOTIF_WM_HINTS", 0 );
- hints.flags = MWM_HINTS_DECORATIONS;
- hints.decorations = 0;
- XChangeProperty( dpy, window, hints_atom, hints_atom, 32,
- PropModeReplace, (unsigned char*)&hints, 5 );
- }
- XMapWindow(dpy, window);
- XIfEvent(dpy, &event, WaitForMapNotify, (char*)window);
- return window;
- }
-
- /*
- * Control points of the torus in Bezier form. Can be rendered
- * using OpenGL evaluators.
- */
- static GLfloat torusbezierpts[] = {
- 4.0, 0.0, 0.0, 4.0, 2.0, 0.0, 1.0, 2.0, 3.0, 0.0, 1.0, 2.0,
- 3.0, 0.0, 1.0, 2.0, 4.0, 0.0, 1.0, 2.0, 8.0, 0.0, 0.0, 4.0,
- 8.0, 0.0, 0.0, 4.0, 4.0, 0.0,-1.0, 2.0, 3.0, 0.0,-1.0, 2.0,
- 3.0, 0.0,-1.0, 2.0, 2.0, 0.0,-1.0, 2.0, 4.0, 0.0, 0.0, 4.0,
- 2.0,-2.0, 0.0, 2.0, 1.0,-1.0, 0.5, 1.0, 1.5,-1.5, 0.5, 1.0,
- 1.5,-1.5, 0.5, 1.0, 2.0,-2.0, 0.5, 1.0, 4.0,-4.0, 0.0, 2.0,
- 4.0,-4.0, 0.0, 2.0, 2.0,-2.0,-0.5, 1.0, 1.5,-1.5,-0.5, 1.0,
- 1.5,-1.5,-0.5, 1.0, 1.0,-1.0,-0.5, 1.0, 2.0,-2.0, 0.0, 2.0,
- 0.0,-2.0, 0.0, 2.0, 0.0,-1.0, 0.5, 1.0, 0.0,-1.5, 0.5, 1.0,
- 0.0,-1.5, 0.5, 1.0, 0.0,-2.0, 0.5, 1.0, 0.0,-4.0, 0.0, 2.0,
- 0.0,-4.0, 0.0, 2.0, 0.0,-2.0,-0.5, 1.0, 0.0,-1.5,-0.5, 1.0,
- 0.0,-1.5,-0.5, 1.0, 0.0,-1.0,-0.5, 1.0, 0.0,-2.0, 0.0, 2.0,
- 0.0,-2.0, 0.0, 2.0, 0.0,-1.0, 0.5, 1.0, 0.0,-1.5, 0.5, 1.0,
- 0.0,-1.5, 0.5, 1.0, 0.0,-2.0, 0.5, 1.0, 0.0,-4.0, 0.0, 2.0,
- 0.0,-4.0, 0.0, 2.0, 0.0,-2.0,-0.5, 1.0, 0.0,-1.5,-0.5, 1.0,
- 0.0,-1.5,-0.5, 1.0, 0.0,-1.0,-0.5, 1.0, 0.0,-2.0, 0.0, 2.0,
- -2.0,-2.0, 0.0, 2.0,-1.0,-1.0, 0.5, 1.0,-1.5,-1.5, 0.5, 1.0,
- -1.5,-1.5, 0.5, 1.0,-2.0,-2.0, 0.5, 1.0,-4.0,-4.0, 0.0, 2.0,
- -4.0,-4.0, 0.0, 2.0,-2.0,-2.0,-0.5, 1.0,-1.5,-1.5,-0.5, 1.0,
- -1.5,-1.5,-0.5, 1.0,-1.0,-1.0,-0.5, 1.0,-2.0,-2.0, 0.0, 2.0,
- -4.0, 0.0, 0.0, 4.0,-2.0, 0.0, 1.0, 2.0,-3.0, 0.0, 1.0, 2.0,
- -3.0, 0.0, 1.0, 2.0,-4.0, 0.0, 1.0, 2.0,-8.0, 0.0, 0.0, 4.0,
- -8.0, 0.0, 0.0, 4.0,-4.0, 0.0,-1.0, 2.0,-3.0, 0.0,-1.0, 2.0,
- -3.0, 0.0,-1.0, 2.0,-2.0, 0.0,-1.0, 2.0,-4.0, 0.0, 0.0, 4.0,
- -4.0, 0.0, 0.0, 4.0,-2.0, 0.0, 1.0, 2.0,-3.0, 0.0, 1.0, 2.0,
- -3.0, 0.0, 1.0, 2.0,-4.0, 0.0, 1.0, 2.0,-8.0, 0.0, 0.0, 4.0,
- -8.0, 0.0, 0.0, 4.0,-4.0, 0.0,-1.0, 2.0,-3.0, 0.0,-1.0, 2.0,
- -3.0, 0.0,-1.0, 2.0,-2.0, 0.0,-1.0, 2.0,-4.0, 0.0, 0.0, 4.0,
- -2.0, 2.0, 0.0, 2.0,-1.0, 1.0, 0.5, 1.0,-1.5, 1.5, 0.5, 1.0,
- -1.5, 1.5, 0.5, 1.0,-2.0, 2.0, 0.5, 1.0,-4.0, 4.0, 0.0, 2.0,
- -4.0, 4.0, 0.0, 2.0,-2.0, 2.0,-0.5, 1.0,-1.5, 1.5,-0.5, 1.0,
- -1.5, 1.5,-0.5, 1.0,-1.0, 1.0,-0.5, 1.0,-2.0, 2.0, 0.0, 2.0,
- 0.0, 2.0, 0.0, 2.0, 0.0, 1.0, 0.5, 1.0, 0.0, 1.5, 0.5, 1.0,
- 0.0, 1.5, 0.5, 1.0, 0.0, 2.0, 0.5, 1.0, 0.0, 4.0, 0.0, 2.0,
- 0.0, 4.0, 0.0, 2.0, 0.0, 2.0,-0.5, 1.0, 0.0, 1.5,-0.5, 1.0,
- 0.0, 1.5,-0.5, 1.0, 0.0, 1.0,-0.5, 1.0, 0.0, 2.0, 0.0, 2.0,
- 0.0, 2.0, 0.0, 2.0, 0.0, 1.0, 0.5, 1.0, 0.0, 1.5, 0.5, 1.0,
- 0.0, 1.5, 0.5, 1.0, 0.0, 2.0, 0.5, 1.0, 0.0, 4.0, 0.0, 2.0,
- 0.0, 4.0, 0.0, 2.0, 0.0, 2.0,-0.5, 1.0, 0.0, 1.5,-0.5, 1.0,
- 0.0, 1.5,-0.5, 1.0, 0.0, 1.0,-0.5, 1.0, 0.0, 2.0, 0.0, 2.0,
- 2.0, 2.0, 0.0, 2.0, 1.0, 1.0, 0.5, 1.0, 1.5, 1.5, 0.5, 1.0,
- 1.5, 1.5, 0.5, 1.0, 2.0, 2.0, 0.5, 1.0, 4.0, 4.0, 0.0, 2.0,
- 4.0, 4.0, 0.0, 2.0, 2.0, 2.0,-0.5, 1.0, 1.5, 1.5,-0.5, 1.0,
- 1.5, 1.5,-0.5, 1.0, 1.0, 1.0,-0.5, 1.0, 2.0, 2.0, 0.0, 2.0,
- 4.0, 0.0, 0.0, 4.0, 2.0, 0.0, 1.0, 2.0, 3.0, 0.0, 1.0, 2.0,
- 3.0, 0.0, 1.0, 2.0, 4.0, 0.0, 1.0, 2.0, 8.0, 0.0, 0.0, 4.0,
- 8.0, 0.0, 0.0, 4.0, 4.0, 0.0,-1.0, 2.0, 3.0, 0.0,-1.0, 2.0,
- 3.0, 0.0,-1.0, 2.0, 2.0, 0.0,-1.0, 2.0, 4.0, 0.0, 0.0, 4.0,
- };
-
- /*
- * Control points of a torus in NURBS form. Can be rendered using
- * the GLU NURBS routines.
- */
- static GLfloat torusnurbpts[] = {
- 4.0, 0.0, 0.0, 4.0, 2.0, 0.0, 1.0, 2.0, 4.0, 0.0, 1.0, 2.0,
- 8.0, 0.0, 0.0, 4.0, 4.0, 0.0,-1.0, 2.0, 2.0, 0.0,-1.0, 2.0,
- 4.0, 0.0, 0.0, 4.0, 2.0,-2.0, 0.0, 2.0, 1.0,-1.0, 0.5, 1.0,
- 2.0,-2.0, 0.5, 1.0, 4.0,-4.0, 0.0, 2.0, 2.0,-2.0,-0.5, 1.0,
- 1.0,-1.0,-0.5, 1.0, 2.0,-2.0, 0.0, 2.0,-2.0,-2.0, 0.0, 2.0,
- -1.0,-1.0, 0.5, 1.0,-2.0,-2.0, 0.5, 1.0,-4.0,-4.0, 0.0, 2.0,
- -2.0,-2.0,-0.5, 1.0,-1.0,-1.0,-0.5, 1.0,-2.0,-2.0, 0.0, 2.0,
- -4.0, 0.0, 0.0, 4.0,-2.0, 0.0, 1.0, 2.0,-4.0, 0.0, 1.0, 2.0,
- -8.0, 0.0, 0.0, 4.0,-4.0, 0.0,-1.0, 2.0,-2.0, 0.0,-1.0, 2.0,
- -4.0, 0.0, 0.0, 4.0,-2.0, 2.0, 0.0, 2.0,-1.0, 1.0, 0.5, 1.0,
- -2.0, 2.0, 0.5, 1.0,-4.0, 4.0, 0.0, 2.0,-2.0, 2.0,-0.5, 1.0,
- -1.0, 1.0,-0.5, 1.0,-2.0, 2.0, 0.0, 2.0, 2.0, 2.0, 0.0, 2.0,
- 1.0, 1.0, 0.5, 1.0, 2.0, 2.0, 0.5, 1.0, 4.0, 4.0, 0.0, 2.0,
- 2.0, 2.0,-0.5, 1.0, 1.0, 1.0,-0.5, 1.0, 2.0, 2.0, 0.0, 2.0,
- 4.0, 0.0, 0.0, 4.0, 2.0, 0.0, 1.0, 2.0, 4.0, 0.0, 1.0, 2.0,
- 8.0, 0.0, 0.0, 4.0, 4.0, 0.0,-1.0, 2.0, 2.0, 0.0,-1.0, 2.0,
- 4.0, 0.0, 0.0, 4.0,
- };
-